/*
 * Copyright (C) 2009 Otávio Scherer Garcia
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.googlecode.technorati4j.entity;

import java.util.Arrays;
import java.util.List;

import com.googlecode.technorati4j.enums.Authority;
import com.googlecode.technorati4j.enums.ResponseFormat;

/**
 * Request entity for search API.
 * 
 * @author Otávio Scherer Garcia
 * @version $Revision$
 */
public final class SearchRequest
    implements Request {

    /** The Technorati API key. */
    private String key;

    /**
     * Word list to search.
     */
    private List<String> words;

    /**
     * This allows you to request an output format, which by default is set to xml. At the moment only the XML (xml) and
     * RSS (rss) formats are supported. We plan to support the Atom Syndication Format as well as XOXO in the near
     * future.
     */
    private ResponseFormat format;

    /**
     * Set this to a ISO 639-1 two character language code to retrieve results specific to that language. This feature
     * is currently beta and may not work for all languages. See
     * http://www.loc.gov/standards/iso639-2/php/English_list.php for more information.
     */
    private String language;

    /**
     * Set this to filter results to those from blogs with at least the Technorati Authority specified. Technorati
     * calculates a blog's authority by how many people link to it. Filtering by authority is a good way to refine your
     * search results.
     */
    private Authority authority;

    /**
     * Set this to a number larger than 0 and you'll get the start+20 freshest items (links or blogs), e.g. set it to
     * 20+1, and you'll get the second page of rankings 21-40.
     */
    private int start;

    /**
     * Set this to a number larger than 0 and smaller or equal to 100 and it will return limit number of links for a
     * query. By default this value is 20.
     */
    private int limit;

    /**
     * Set this to 1 to have each link result embellished with any user information associated with a link result's
     * parent blog.
     */
    private boolean claim;

    /**
     * The default constructor.
     */
    public SearchRequest() {
    }

    /**
     * Constructor with mandatory attributes.
     * 
     * @param key The key parameter.
     * @param words The list of words to use in the search.
     */
    public SearchRequest(String key, List<String> words) {
        setKey(key);
        setWords(words);
    }

    /**
     * Constructor with mandatory attributes.
     * 
     * @param key The key parameter.
     * @param words The list of words to use in the search.
     */
    public SearchRequest(String key, String... words) {
        setKey(key);
        setWords(words);
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public List<String> getWords() {
        return words;
    }

    public void setWords(List<String> words) {
        this.words = words;
    }

    public void setWords(String... words) {
        this.words = Arrays.asList(words);
    }

    public ResponseFormat getFormat() {
        return format;
    }

    public void setFormat(ResponseFormat format) {
        this.format = format;
    }

    public String getLanguage() {
        return language;
    }

    public void setLanguage(String language) {
        this.language = language;
    }

    public Authority getAuthority() {
        return authority;
    }

    public void setAuthority(Authority authority) {
        this.authority = authority;
    }

    public int getStart() {
        return start;
    }

    public void setStart(int start) {
        this.start = start;
    }

    public int getLimit() {
        return limit;
    }

    public void setLimit(int limit) {
        this.limit = limit;
    }

    public boolean isClaim() {
        return claim;
    }

    public void setClaim(boolean claim) {
        this.claim = claim;
    }

    public String getParameters() {
        final StringBuilder str = new StringBuilder();
        str.append("key=");
        str.append(this.key);

        str.append("&query=");
        for (int i = 0; i < words.size(); i++) {
            str.append(words.get(i));

            if (i < words.size() - 1) {
                str.append("+");
            }
        }

        if (format != null) {
            str.append("&format=");
            str.append(format);
        }

        if (language != null) {
            str.append("&language=");
            str.append(language);
        }

        if (authority != null) {
            str.append("&authority=");
            str.append(authority);
        }

        if (start > 0) {
            str.append("&start=");
            str.append(start);
        }

        if (limit > 0 && limit <= 100) {
            str.append("&limit=");
            str.append(limit);
        }

        if (claim) {
            str.append("&claim=1");
        }

        return str.toString();
    }
}
